package com.xd.shading.config.sharding;

import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.driver.jdbc.core.datasource.ShardingSphereDataSource;

import javax.sql.DataSource;
import java.sql.*;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;


/**
 * 根据数据库的语法差异，调整statement 的语法
 */
@Slf4j
public class DatabaseTableUtil {


    /**
     * 查询实际表名
     * @param datasource
     * @param logicTableName
     * @return
     */
    public static Set<String> getActuallyTableName(DataSource datasource, String logicTableName) {
        Set<String> tables = new LinkedHashSet<>();
        Connection connection = null;
        try {
            //Collection<String> actualTables = database.getSchema("logic_db").getTable("t_order").getActualTables();
            connection = datasource.getConnection();
            String sql = "SHOW TABLES LIKE '" + logicTableName + "_"+"%'";
            //String sql = "SELECT table_name FROM information_schema.tables where table_name like 't_order_%'";
            Statement statement = connection.createStatement();
            ResultSet resultSet = statement.executeQuery(sql);
            while (resultSet.next()) {
                String tableName = resultSet.getString(1);
                log.info("查询的表名为:{}",tableName);
                tables.add(resultSet.getString(1));
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            try {
                connection.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
        return tables;
    }

    /**
     * 创建数据库表, 并开启双重验证判断表是否创建成功
     *
     * @param dynamicTable   逻辑表名称
     * @param targetTable 实际表名称
     */
    public static boolean createTableLike(DataSource dataSource, String dynamicTable, String targetTable) {
        Connection connection = null;
        try {
            connection = dataSource.getConnection();
            Statement statement = connection.createStatement();
            ResultSet queryResult = statement.executeQuery("SHOW TABLES LIKE '"+targetTable+"'");
            if(queryResult.next()){
                return true;
            }
            statement.execute("CREATE TABLE " + targetTable + " LIKE " + dynamicTable + ";");
            // double check
            ResultSet resultSet = statement.executeQuery("SHOW TABLES LIKE '" + targetTable + "';");
            if (resultSet.next()) {
                log.info("Auto create actually table {} success", targetTable);
                return resultSet.getString(1) != null;
            } else {
                log.info("Auto create actually table {} failure", targetTable);
                return false;
            }
        } catch (SQLException e) {
            // already exists
            if (e.getMessage() != null && e.getMessage().contains("already exists")) {
                return true;
            }
            log.error("fail to create actuallyTable '{}' from logicTable '{}'",
                    targetTable, dynamicTable, e);
            return false;
        }finally {
            try {
                connection.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }

}
